﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Web;
using System.Drawing.Imaging;
using ImageResizer;
namespace He.Common
{
    public class ImageHelper
    {
        #region 图片自适应
        /// <summary>
        /// 图片自适应
        /// </summary>
        /// <param name="imgSrc">图片地址</param>
        /// <param name="imgHref">点击图片的链接地址</param>
        /// <param name="width">最大宽度</param>
        /// <param name="height">最大高度</param>
        /// <returns></returns>
        public static string ImgFix(object imgSrc, object imgHref, int width, int height)
        {
            string src = imgSrc.ToString();
            string href = imgHref.ToString();
            return ImgFix(src, href, width, height);
        }

        /// <summary>
        /// 图片自适应（服务端方式）
        /// </summary>
        /// <param name="imgSrc"></param>
        /// <param name="containerWidth"></param>
        /// <param name="containerHeight"></param>
        /// <returns></returns>
        public static string ImgFix(object imgSrc, decimal containerWidth, decimal containerHeight, string otherAttr)
        {
            string limit = string.Empty;
            string imgPath = PathHelper.MapPath(imgSrc.ToString());
            if (System.IO.File.Exists(imgPath))
            {
                System.Drawing.Image img = System.Drawing.Image.FromFile(imgPath);
                decimal imgRatio = (decimal)img.Width / (decimal)img.Height;
                decimal containerRatio = containerWidth / containerHeight;
                if (imgRatio > containerRatio)
                {
                    limit = string.Format(" width='{0}' ", containerWidth);
                }
                else
                {
                    limit = string.Format(" height='{0}' ", containerHeight);
                }
                img.Dispose();
                return string.Format("<img src='{0}' {1} {2} />", imgSrc.ToString(), limit, otherAttr);
            }
            else
            {
                return "<img src=\"\" border=\"0\">";
            }
        }
        #endregion

        #region 缩略图

        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            ImageThumbnailMake.MakeThumbnail(originalImagePath, thumbnailPath, width, height, mode);
        }

        #endregion

        #region ImageResizer缩略图
        public static void CompressImage(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            ResizeSettings settings = new ResizeSettings();
            settings.Width = width;                                                            //图片宽度
            settings.Height = height;                                                          //图片高度
            settings.Mode = GetFitMode(mode);                                                  //自适应方式参数
            if (File.Exists(PathHelper.MapPath(originalImagePath)))
            {
                Image srcImg = Image.FromFile(PathHelper.MapPath(originalImagePath));
                using (MemoryStream outStream = new MemoryStream())
                {
                    ImageBuilder.Current.Build(srcImg, outStream, settings, true);
                    Bitmap bitmap = new Bitmap(outStream);
                    try
                    {
                        //保存缩略图
                        if (!Directory.Exists(PathHelper.MapPath("/uploadfiles/thumb/")))
                        {
                            Directory.CreateDirectory(PathHelper.MapPath("/uploadfiles/thumb/"));
                        }

                        bitmap.Save(PathHelper.MapPath(thumbnailPath));

                    }
                    catch (System.Exception e)
                    {
                        throw e;
                    }
                    finally
                    {
                        bitmap.Dispose();
                        outStream.Dispose();
                        srcImg.Dispose();
                    }
                }
            }
        }

        public static FitMode GetFitMode(string mode)
        {
            if (mode == "pad")
            {
                return FitMode.Pad;
            }
            else if (mode == "cut")
            {
                return FitMode.Crop;
            }
            else if (mode == "max")
            {
                return FitMode.Max;
            }
            else
            {
                return FitMode.Max;
            }
        }
        #endregion

        #region 水印图片
        /// <summary>
        /// 图片水印
        /// </summary>
        /// <param name="imgPath">服务器图片相对路径</param>
        /// <param name="filename">保存文件名</param>
        /// <param name="watermarkFilename">水印文件相对路径</param>
        /// <param name="watermarkStatus">图片水印位置 0=不使用 1=左上 2=中上 3=右上 4=左中  9=右下</param>
        /// <param name="quality">附加水印图片质量,0-100</param>
        /// <param name="watermarkTransparency">水印的透明度 1--10 10为不透明</param>
        public static void AddImageSignPic(string imgPath, string filename, string watermarkFilename, int watermarkStatus, int quality, int watermarkTransparency)
        {
            byte[] _ImageBytes = File.ReadAllBytes(PathHelper.MapPath(imgPath));
            Image img = Image.FromStream(new System.IO.MemoryStream(_ImageBytes));
            filename = HttpContext.Current.Server.MapPath(filename);

            if (watermarkFilename.StartsWith("/") == false)
                watermarkFilename = "/" + watermarkFilename;
            watermarkFilename = PathHelper.MapPath(watermarkFilename);
            if (!File.Exists(watermarkFilename))
                return;
            Graphics g = Graphics.FromImage(img);
            //设置高质量插值法
            //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //设置高质量,低速度呈现平滑程度
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            Image watermark = new Bitmap(watermarkFilename);

            if (watermark.Height >= img.Height || watermark.Width >= img.Width)
                return;

            ImageAttributes imageAttributes = new ImageAttributes();
            ColorMap colorMap = new ColorMap();

            colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
            colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
            ColorMap[] remapTable = { colorMap };

            imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

            float transparency = 0.5F;
            if (watermarkTransparency >= 1 && watermarkTransparency <= 10)
                transparency = (watermarkTransparency / 10.0F);


            float[][] colorMatrixElements = {
												new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  transparency, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
											};

            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            int xpos = 0;
            int ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 2:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 3:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 4:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 5:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 6:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 7:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 8:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 9:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
            }

            g.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType.IndexOf("jpeg") > -1)
                    ici = codec;
            }
            EncoderParameters encoderParams = new EncoderParameters();
            long[] qualityParam = new long[1];
            if (quality < 0 || quality > 100)
                quality = 80;

            qualityParam[0] = quality;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
            encoderParams.Param[0] = encoderParam;

            if (ici != null)
                img.Save(filename, ici, encoderParams);
            else
                img.Save(filename);

            g.Dispose();
            img.Dispose();
            watermark.Dispose();
            imageAttributes.Dispose();
        }

        /// <summary>
        /// 文字水印
        /// </summary>
        /// <param name="imgPath">服务器图片相对路径</param>
        /// <param name="filename">保存文件名</param>
        /// <param name="watermarkText">水印文字</param>
        /// <param name="watermarkStatus">图片水印位置 0=不使用 1=左上 2=中上 3=右上 4=左中  9=右下</param>
        /// <param name="quality">附加水印图片质量,0-100</param>
        /// <param name="fontname">字体</param>
        /// <param name="fontsize">字体大小</param>
        public static void AddImageSignText(string imgPath, string filename, string watermarkText, int watermarkStatus, int quality, string fontname, int fontsize)
        {
            byte[] _ImageBytes = File.ReadAllBytes(HttpContext.Current.Server.MapPath(imgPath));
            Image img = Image.FromStream(new System.IO.MemoryStream(_ImageBytes));
            filename = HttpContext.Current.Server.MapPath(filename);

            Graphics g = Graphics.FromImage(img);
            Font drawFont = new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Pixel);
            SizeF crSize;
            crSize = g.MeasureString(watermarkText, drawFont);

            float xpos = 0;
            float ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (float)img.Width * (float).01;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 2:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = (float)img.Height * (float).01;
                    break;
                case 3:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = (float)img.Height * (float).01;
                    break;
                case 4:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 5:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 6:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                    break;
                case 7:
                    xpos = (float)img.Width * (float).01;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 8:
                    xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
                case 9:
                    xpos = ((float)img.Width * (float).99) - crSize.Width;
                    ypos = ((float)img.Height * (float).99) - crSize.Height;
                    break;
            }

            g.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + 1, ypos + 1);
            g.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos);

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo ici = null;
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType.IndexOf("jpeg") > -1)
                    ici = codec;
            }
            EncoderParameters encoderParams = new EncoderParameters();
            long[] qualityParam = new long[1];
            if (quality < 0 || quality > 100)
                quality = 80;

            qualityParam[0] = quality;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
            encoderParams.Param[0] = encoderParam;

            if (ici != null)
                img.Save(filename, ici, encoderParams);
            else
                img.Save(filename);

            g.Dispose();
            img.Dispose();
        }

        #endregion

        #region 生成验证码图片

        public static ValidateCode NewValidateCode()
        {
            return new ValidateCode();
        }

        #endregion

        #region 复制图片 
        /// <summary>
        /// 复制图片
        /// </summary>
        /// <param name="originalImagePath">原始图片相对路径</param>
        /// <param name="savePath">保存图片相对路径</param>
        public static void CopyImage(string originalImagePath, string savePath)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(PathHelper.MapPath(originalImagePath));
            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;       

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(ow, oh);
            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);
            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, ow, oh),
                new System.Drawing.Rectangle(x, y, ow, oh),
                System.Drawing.GraphicsUnit.Pixel);

            try
            {
                //保存缩略图
                bitmap.Save(PathHelper.MapPath(savePath));
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }
        #endregion
    }


    #region 验证码图片
    /// <summary>
    /// 验证码
    /// </summary>
    public class ValidateCode
    {
        /// <summary>
        /// 字符类型
        /// </summary>
        [Flags]
        public enum En_CharKind
        {
            /// <summary>
            /// 汉字（默认，不可和其他字符类型枚举合用）
            /// </summary>
            Chinese = 0,
            /// <summary>
            /// 大写字母
            /// </summary>
            Upper = 1,
            /// <summary>
            /// 小写字母
            /// </summary>
            Lower = 2,
            /// <summary>
            /// 数字
            /// </summary>
            Number = 4
        }

        /// <summary>
        /// 验证码配置信息
        /// </summary>
        public class ValidateCodeConfiger
        {
            private int _fontSize;
            /// <summary>
            /// 字体大小
            /// </summary>
            public int FontSize
            {
                get { return _fontSize; }
                set { _fontSize = value; }
            }

            private int _charSpacing;
            /// <summary>
            /// 字符间隔
            /// </summary>
            public int CharSpacing
            {
                get { return _charSpacing; }
                set { _charSpacing = value; }
            }

            private int _width;
            /// <summary>
            /// 图片宽
            /// </summary>
            public int Width
            {
                get { return _width; }
                set { _width = value; }
            }
            private int _height;
            /// <summary>
            /// 图片高
            /// </summary>
            public int Height
            {
                get { return _height; }
                set { _height = value; }
            }

            private int _charNum;
            /// <summary>
            /// 字符个数
            /// </summary>
            public int CharNum
            {
                get { return _charNum; }
                set { _charNum = value; }
            }

            private En_CharKind _charKind;
            /// <summary>
            /// 字符类型
            /// </summary>
            public En_CharKind CharKind
            {
                get { return _charKind; }
                set { _charKind = value; }
            }

            private NoiseLine _noiseLine;
            /// <summary>
            /// 噪点（线）数
            /// </summary>
            public NoiseLine Noise
            {
                get { return _noiseLine; }
                set { _noiseLine = value; }
            }

            private Color _backgroundColor;
            /// <summary>
            /// 背景颜色
            /// </summary>
            public Color BackgroundColor
            {
                get { return _backgroundColor; }
                set { _backgroundColor = value; }
            }

            private Color _borderColor;
            /// <summary>
            /// 边框颜色
            /// </summary>
            public Color BorderColor
            {
                get { return _borderColor; }
                set { _borderColor = value; }
            }

            /// <summary>
            /// 获取一个验证码配置信息实例
            /// </summary>
            /// <returns></returns>
            public static ValidateCodeConfiger GetInstance()
            {
                ValidateCodeConfiger configer = new ValidateCodeConfiger();

                configer.CharNum = 4;
                configer.FontSize = 14;
                configer.CharSpacing = 4;
                configer.Width = (configer.CharNum * configer.FontSize) + ((configer.CharNum) * configer.CharSpacing);
                configer.Height = configer.FontSize + 6;

                //configer.CharKind = En_CharKind.Chinese;
                configer.CharKind = En_CharKind.Lower | En_CharKind.Number;

                configer.Noise = NoiseLine.GetInstance();

                configer.BorderColor = Color.Black;
                configer.BackgroundColor = Color.White;

                return configer;
            }
        }

        /// <summary>
        /// 背景噪线
        /// </summary>
        public class NoiseLine
        {
            public NoiseLine()
            {
                BorderColor = Color.Silver;
            }

            private int _borderWidth;
            /// <summary>
            /// 线的宽度
            /// </summary>
            public int BorderWidth
            {
                get { return _borderWidth; }
                set { _borderWidth = value; }
            }

            private Color _borderColor;
            /// <summary>
            /// 线的颜色
            /// </summary>
            public Color BorderColor
            {
                get { return _borderColor; }
                set { _borderColor = value; }
            }

            private int _count;
            /// <summary>
            /// 线的数量
            /// </summary>
            public int Count
            {
                get { return _count; }
                set { _count = value; }
            }

            /// <summary>
            /// 获取一个背景噪线实例
            /// </summary>
            /// <returns></returns>
            public static NoiseLine GetInstance()
            {
                NoiseLine instance = new NoiseLine();

                instance.BorderColor = Color.LightGray;
                instance.BorderWidth = 1;
                instance.Count = 25;

                return instance;
            }
        }

        //////////////////////////////////////////////////////////////////////////////

        #region 成员
        private ValidateCodeConfiger _configer;
        /// <summary>
        /// 验证码配置
        /// </summary>
        public ValidateCodeConfiger Configer
        {
            get { return _configer; }
            set { _configer = value; }
        }

        /// <summary>
        /// 验证码字符串
        /// </summary>
        private string _codeString;

        /// <summary>
        /// 验证码图片
        /// </summary>
        private Bitmap _codeImg;

        /// <summary>
        /// 验证码输出流
        /// </summary>
        private MemoryStream _codeStream;
        #endregion

        #region 构造方法
        /// <summary>
        /// 构造方法
        /// </summary>
        public ValidateCode()
        {
            Configer = ValidateCodeConfiger.GetInstance();
            CreateCode();
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="configer">验证码配置</param>
        public ValidateCode(ValidateCodeConfiger configer)
        {
            Configer = configer;
            AmendConfiger();
            CreateCode();
        }
        #endregion

        #region 公有方法
        /// <summary>
        /// 重新加载缩略图
        /// </summary>
        public void Reload()
        {
            CreateCode();
        }

        /// <summary>
        /// 获取验证码字符串
        /// </summary>
        /// <returns></returns>
        public string GetString()
        {
            return _codeString;
        }

        /// <summary>
        /// 获取验证码图片
        /// </summary>
        public Bitmap GetImg()
        {
            return _codeImg;
        }

        /// <summary>
        /// 获取验证码输出流
        /// </summary>
        public MemoryStream GetStream()
        {
            return _codeStream;
        }

        /// <summary>
        /// 获取Byte数组
        /// </summary>
        /// <returns></returns>
        public byte[] GetByteArray()
        {
            return _codeStream.ToArray();
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 修正配置信息
        /// </summary>
        private void AmendConfiger()
        {
            if (Configer.CharNum <= 0)
            {
                Configer.CharNum = 4;
            }
            if (Configer.FontSize <= 0)
            {
                Configer.FontSize = 14;
            }
            if (Configer.CharSpacing <= 0)
            {
                Configer.CharSpacing = 4;
            }
            if (Configer.Width <= 0)
            {
                Configer.Width = (Configer.CharNum * Configer.FontSize) + ((Configer.CharNum) * Configer.CharSpacing);
            }
            if (Configer.Height <= 0)
            {
                Configer.Height = Configer.FontSize + 6;
            }
            if (Configer.Noise == null)
            {
                Configer.Noise = NoiseLine.GetInstance();
            }
        }

        /// <summary>
        /// 创建验证码
        /// </summary>
        private void CreateCode()
        {
            // 获取验证码字符串
            if (Configer.CharKind == En_CharKind.Chinese)
            {
                // 生成中文字符串
                _codeString = GetCnCodeString();
            }
            else
            {
                // 生成英文、数字字符串
                _codeString = GetEnNumCodeString();
            }

            // 获取验证码图片
            _codeImg = CreateImages();
            // 获取验证码输出流
            _codeStream = GetCodeStream();
        }

        /// <summary>
        ///  获取英文、数字字符串
        /// </summary>
        /// <returns></returns>
        private string GetEnNumCodeString()
        {
            string numChars = "0123456789";
            string lowerChars = "abcdefghijklmnopqrstuvwxyz";
            string upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            int maxIndex = -1;
            string charsToBeChoiced = "";
            string charKinds = "," + Configer.CharKind.ToString().Replace(" ", "") + ",";

            if (charKinds.IndexOf("," + En_CharKind.Number.ToString() + ",") >= 0)
            {
                charsToBeChoiced += numChars;
                maxIndex += numChars.Length;
            }
            if (charKinds.IndexOf("," + En_CharKind.Lower.ToString() + ",") >= 0)
            {
                charsToBeChoiced += lowerChars;
                maxIndex += lowerChars.Length;
            }
            if (charKinds.IndexOf("," + En_CharKind.Upper.ToString() + ",") >= 0)
            {
                charsToBeChoiced += upperChars;
                maxIndex += upperChars.Length;
            }

            Random rand = new Random();
            string re = "";
            for (int i = 0; i < Configer.CharNum; i++)
            {
                re += charsToBeChoiced.Substring(rand.Next(maxIndex), 1);
            }
            return re;
        }

        /// <summary>
        /// 获取中文验证码字符串
        /// </summary>
        /// <returns></returns>
        private string GetCnCodeString()
        {
            // 获取编码
            System.Text.Encoding encoding = System.Text.Encoding.Default;

            // 产生随机中文汉字编码
            object[] bytes = CreateCnCode();


            string[] str = new string[Configer.CharNum];

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = 0; i < Configer.CharNum; i++)
            {
                // 根据汉字编码的字节数组解码出中文汉字
                str[i] = encoding.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));
                sb.Append(str[i].ToString());
            }
            return sb.ToString();
        }

        /// <summary>
        /// 产生随机中文汉字编码
        /// </summary>
        /// <param name="strlength"></param>
        /// <returns></returns>
        private object[] CreateCnCode()
        {
            //定义一个字符串数组储存汉字编码的组成元素
            string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
            Random rnd = new Random();
            object[] bytes = new object[Configer.CharNum];

            for (int i = 0; i < Configer.CharNum; i++)
            {
                //区位码第1位
                int r1 = rnd.Next(11, 14);
                string str_r1 = rBase[r1].Trim();

                //区位码第2位
                rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);
                int r2;
                if (r1 == 13)
                {
                    r2 = rnd.Next(0, 7);
                }
                else
                {
                    r2 = rnd.Next(0, 16);
                }
                string str_r2 = rBase[r2].Trim();

                //区位码第3位
                rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);
                int r3 = rnd.Next(10, 16);
                string str_r3 = rBase[r3].Trim();

                //区位码第4位
                rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
                int r4;
                if (r3 == 10)
                {
                    r4 = rnd.Next(1, 16);
                }
                else if (r3 == 15)
                {
                    r4 = rnd.Next(0, 15);
                }
                else
                {
                    r4 = rnd.Next(0, 16);
                }
                string str_r4 = rBase[r4].Trim();

                //定义两个字节变量存储产生的随机汉字区位码
                byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);
                byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);

                //将两个字节变量存储在字节数组中
                byte[] str_r = new byte[] { byte1, byte2 };

                //将产生的一个汉字的字节数组放入object数组中
                bytes.SetValue(str_r, i);
            }
            return bytes;
        }

        /// <summary>
        /// 创建验证码图片
        /// </summary>
        /// <returns></returns>
        private Bitmap CreateImages()
        {
            // 创建位图
            System.Drawing.Bitmap image = new System.Drawing.Bitmap(Configer.Width, Configer.Height);
            // 创建画板
            Graphics graphics = Graphics.FromImage(image);
            // 清除背景色
            graphics.Clear(Configer.BackgroundColor);
            // 前景颜色
            Color[] colors = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };

            // 随机数生成器
            Random rand = new Random();

            // 画背景线
            for (int i = 0; i < Configer.Noise.Count; i++)
            {
                int x = rand.Next(image.Width);
                int y = rand.Next(image.Height);
                int x1 = rand.Next(image.Width);
                int x2 = rand.Next(image.Width);
                int y1 = rand.Next(image.Height);
                int y2 = rand.Next(image.Height);
                graphics.DrawLine(new Pen(Configer.Noise.BorderColor, Configer.Noise.BorderWidth), x1, y1, x2, y2);
            }

            // 画字符
            int colorMaxIndex = colors.Length - 1;
            float fontSizePt = ((float)(Configer.FontSize * 3) / 4);
            float preX = ((float)((Configer.FontSize + Configer.CharSpacing * 2) * 3) / 4);
            float preY = 3;
            for (int i = 0; i < Configer.CharNum; i++)
            {
                int cindex = rand.Next(colorMaxIndex);
                Font font = new System.Drawing.Font("宋体", fontSizePt);
                Brush brush = new System.Drawing.SolidBrush(colors[cindex]);
                graphics.DrawString(_codeString.Substring(i, 1), font, brush, (i * preX), preY);
            }

            // 画边框
            if (Configer.BorderColor != null)
            {
                graphics.DrawRectangle(new Pen(Configer.BorderColor, 0), 0, 0, image.Width - 1, image.Height - 1);
            }

            // 返回图片
            return image;
        }

        /// <summary>
        /// 获取验证码输出流
        /// </summary>
        /// <returns></returns>
        private MemoryStream GetCodeStream()
        {
            MemoryStream stream = new MemoryStream();
            try
            {
                _codeImg.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
            }
            catch
            {
                stream = null;
            }
            return stream;
        }
        #endregion
    }

    #endregion

    #region 新增缩略图
    public class ImageThumbnailMake
    {
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（相对路径）</param>
        /// <param name="thumbnailPath">缩略图路径（相对路径）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param>    
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(PathHelper.MapPath(originalImagePath));
            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case "HW"://指定高宽缩放（可能变形）                
                    break;
                case "W"://指定宽，高按比例                    
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case "H"://指定高，宽按比例
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case "Cut"://指定高宽裁减（不变形）                
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                default:
                    break;
            }

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);
            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
                new System.Drawing.Rectangle(x, y, ow, oh),
                System.Drawing.GraphicsUnit.Pixel);

            try
            {
                //保存缩略图
                bitmap.Save(PathHelper.MapPath(thumbnailPath));
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }
    }

    #endregion
}
